import { User } from "../models/user";
import { Menu } from "../models/menu";
import crypto from "crypto";
import { uid } from "uid";
import { Role } from "../models/role";

const defPwd = "123456";
export default function userModule(app, opt, next) {
  app.get("/detail", async (req, res) => {
    const menu = await Menu.find({}).sort({ order: 1 }).lean();
    const user = await req.getUser(false);
    const role = await Role.findById(user.role);
    const authMap = role.auth.reduce((acc, cur) => {
      return {
        ...acc,
        [cur]: true,
      };
    }, {});
    const tick = (item) => {
      if (item.children && item.children.length > 0) {
        return {
          ...item,
          children: (item.children || []).map(tick),
        };
      }
      return {
        ...item,
        auth: !!authMap[item.key],
      };
    };
    const rmenu = menu
      .map(tick)
      .map((v) => {
        const children = v.children.filter((o) => o.auth);
        if (children.length) {
          return {
            ...v,
            children,
          };
        }
        return false;
      })
      .filter(Boolean);
    return {
      user,
      menu: rmenu,
      role,
    };
  });
  app.get("/list", async (req, res) => {
    const items = await User.aggregate().lookup({
      from: "roles",
      localField: "role",
      foreignField: "_id",
      as: "roleInfo",
    });
    return {
      items,
    };
  });
  app.post("/delete", async (req, res) => {
    return User.deleteOne({ _id: req.body.id });
  });
  app.post("/add", async (req, res) => {
    const { name, role } = req.body;
    if (await User.exists({ name })) {
      throw new Error("用户已存在");
    }
    const user = new User();
    const md5 = crypto.createHash("md5");
    user.name = name;
    user.role = role;
    user.password = md5.update(defPwd).digest("hex");
    await user.save();
    return user;
  });
  app.post("/logout", async (req, rep) => {
    const { authorization } = req.raw.headers;
    const token = authorization.replace("Bearer", "").trim();
    await app.cache.delete(token);
    return {
      msg: "ok",
    };
  });
  app.post("/update", async (req) => {
    const { id, ...rest } = req.body;
    return User.updateOne({ _id: id }, rest);
  });
  app.post(
    "/login",
    {
      config: {
        allowGuest: true,
      },
    },
    async (req, res) => {
      const { username, password } = req.body;

      const user = await User.findOne({ name: username });
      if (!user) {
        throw new Error("用户不存在");
      }
      const md5 = crypto.createHash("md5");
      if (user.password !== md5.update(password).digest("hex")) {
        throw new Error("密码错误");
      }
      const token = uid(32);
      await app.cache.set(token, user, 60 * 60 * 24);
      return { user, token };
    }
  );

  next();
}

export const autoPrefix = "/user";
